#include "utransferwidget.h"
#include "utreeview.h"
#include "widgets/upushbutton.h"
#include "widgets/ulabel.h"

#include <QPainter>
#include <QPainterPath>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QVBoxLayout>
#include <QDebug>

class UTransferWidgetPrivate
{
public:
    UTransferWidgetPrivate(UTransferWidget* q) : q_ptr(q) {}
    ~UTransferWidgetPrivate() {}

    void init();

    void initConnection();

    QWidget* initLeftWidget();

    QWidget* initRightWidget();

private:
    Q_DECLARE_PUBLIC(UTransferWidget)
    UTransferWidget* const q_ptr = Q_NULLPTR;
    ULabel* leftLabel = Q_NULLPTR;
    ULabel* rightLabel = Q_NULLPTR;
    UTreeView* leftView = Q_NULLPTR;
    UTreeView* rightView = Q_NULLPTR;
    UPushButton* leftButton = Q_NULLPTR;
    UPushButton* rightButton = Q_NULLPTR;
    QStandardItemModel* leftModel = Q_NULLPTR;
    QStandardItemModel* rightModel = Q_NULLPTR;
};

void UTransferWidgetPrivate::init()
{
    Q_Q(UTransferWidget);

    QVBoxLayout* layout = new QVBoxLayout;
    leftButton = new UPushButton(q);
    leftButton->setMinimumSize(50, 28);
    leftButton->setIcon(QIcon::fromTheme("leftarrow"));
    leftButton->setEnabled(false);

    rightButton = new UPushButton(q);
    rightButton->setMinimumSize(50, 28);
    rightButton->setIcon(QIcon::fromTheme("rightarrow"));
    rightButton->setEnabled(false);

    layout->addStretch();
    layout->addWidget(rightButton);
    layout->addSpacing(20);
    layout->addWidget(leftButton);
    layout->addStretch();

    QHBoxLayout* mainLayout = new QHBoxLayout;
    mainLayout->addWidget(initLeftWidget());
    mainLayout->addLayout(layout);
    mainLayout->addWidget(initRightWidget());
    q->setLayout(mainLayout);

    initConnection();
}

void UTransferWidgetPrivate::initConnection()
{
    Q_Q(UTransferWidget);

    QObject::connect(leftButton, &UPushButton::clicked, q, &UTransferWidget::onSyncRightData);

    QObject::connect(rightButton, &UPushButton::clicked, q, &UTransferWidget::onSyncLeftData);

    QObject::connect(leftView, &UTreeView::headerCheckStatusChanged, q, [this](const Qt::CheckState & state)
    {
        rightButton->setEnabled(state != Qt::CheckState::Unchecked);
    });

    QObject::connect(rightView, &UTreeView::headerCheckStatusChanged, q, [this](const Qt::CheckState & state)
    {
        leftButton->setEnabled(state != Qt::CheckState::Unchecked);
    });
}

QWidget* UTransferWidgetPrivate::initLeftWidget()
{
    Q_Q(UTransferWidget);
    QWidget* leftWidget = new QWidget(q);
    QVBoxLayout* layout = new QVBoxLayout;
    leftLabel = new ULabel(q);
    leftView = new UTreeView(q);
    leftView->header()->setVisible(true);
    leftView->setRootIsDecorated(false);
    leftView->setCheckColumnIndex(0);
    leftView->setFrameShape(QFrame::StyledPanel);
    leftModel = new QStandardItemModel(leftView);
    leftView->setModel(leftModel);

    layout->addWidget(leftLabel, 0, Qt::AlignLeft | Qt::AlignVCenter);
    layout->addWidget(leftView);
    leftWidget->setLayout(layout);
    return leftWidget;
}

QWidget* UTransferWidgetPrivate::initRightWidget()
{
    Q_Q(UTransferWidget);
    QWidget* rightWidget = new QWidget(q);
    QVBoxLayout* layout = new QVBoxLayout;
    rightLabel = new ULabel(q);
    rightView = new UTreeView(q);
    rightView->header()->setVisible(true);
    rightView->setRootIsDecorated(false);
    rightView->setCheckColumnIndex(0);
    rightView->setFrameShape(QFrame::StyledPanel);
    rightModel = new QStandardItemModel(rightView);
    rightView->setModel(rightModel);

    layout->addWidget(rightLabel, 0, Qt::AlignLeft | Qt::AlignVCenter);
    layout->addWidget(rightView);
    rightWidget->setLayout(layout);
    return rightWidget;
}

UTransferWidget::UTransferWidget(QWidget* parent)
    : QWidget(parent)
    , d_ptr(new UTransferWidgetPrivate(this))
{
    Q_D(UTransferWidget);

    d->init();
}

UTransferWidget::~UTransferWidget()
{
}

void UTransferWidget::setLeftTitle(const QString &name)
{
    Q_D(UTransferWidget);
    d->leftLabel->setText(name);
}

void UTransferWidget::setRightTitle(const QString &name)
{
    Q_D(UTransferWidget);
    d->rightLabel->setText(name);
}

QModelIndexList UTransferWidget::leftSelectModelIndex() const
{
    Q_D(const UTransferWidget);

    QModelIndexList list;
    auto model = d->leftView->model();
    if (nullptr == model)
    {
        return list;
    }
    for (int i = 0; i < model->rowCount(); ++i)
    {
        QModelIndex modelIndex = model->index(i, 0);
        if (modelIndex.data().toBool())
        {
            list.append(modelIndex);
        }
    }
    return list;
}

QModelIndexList UTransferWidget::rightSelectModelIndex() const
{
    Q_D(const UTransferWidget);

    QModelIndexList list;
    auto model = d->rightView->model();
    if (nullptr == model)
    {
        return list;
    }
    for (int i = 0; i < model->rowCount(); ++i)
    {
        QModelIndex modelIndex = model->index(i, 0);
        if (modelIndex.data().toBool())
        {
            list.append(modelIndex);
        }
    }
    return list;
}

QStandardItemModel* UTransferWidget::leftModel()
{
    Q_D(UTransferWidget);
    return d->leftModel;
}

QStandardItemModel* UTransferWidget::rightModel()
{
    Q_D(UTransferWidget);
    return d->rightModel;
}

void UTransferWidget::setLeftColumnWidth(const QList<int> &widths)
{
    Q_D(UTransferWidget);
    for (int i = 0; i < widths.size(); ++i)
    {
        if (i >= d->leftModel->columnCount())
        {
            continue;
        }
        d->leftView->setColumnWidth(i, widths[i]);
    }
}

void UTransferWidget::setRightColumnWidth(const QList<int> &widths)
{
    Q_D(UTransferWidget);
    for (int i = 0; i < widths.size(); ++i)
    {
        if (i >= d->rightModel->columnCount())
        {
            continue;
        }
        d->rightView->setColumnWidth(i, widths[i]);
    }
}

void UTransferWidget::updateHeaderCheckStatus()
{
    Q_D(UTransferWidget);
    d->leftView->updateHeaderCheckStatus();
    d->rightView->updateHeaderCheckStatus();
}

void UTransferWidget::onSyncLeftData()
{
    Q_D(UTransferWidget);
    int count = d->leftModel->rowCount() - 1;
    for (int i = count; i >= 0; i--)
    {
        if (d->leftModel->index(i, 0).data().toBool())
        {
            d->rightModel->appendRow(d->leftModel->takeRow(i));
        }
    }
    if (d->rightModel->columnCount() > 1)
    {
        d->rightModel->sort(1);
    }
    updateHeaderCheckStatus();
}

void UTransferWidget::onSyncRightData()
{
    Q_D(UTransferWidget);
    int count = d->rightModel->rowCount() - 1;
    for (int i = count; i >= 0; i--)
    {
        if (d->rightModel->index(i, 0).data().toBool())
        {
            d->leftModel->appendRow(d->rightModel->takeRow(i));
        }
    }
    if (d->leftModel->columnCount() > 1)
    {
        d->leftModel->sort(1);
    }
    updateHeaderCheckStatus();
}
